#include "stm32f10x.h"                  // Device header
#include "myiic.h"
#include "mpu6050.h"
#include "mpu6050_reg.h"
#define reset_count() i=10000
#define MPU6050_ADD 0XD0

void Mpu6050WriteReg(uint8_t add,uint8_t data)//写寄存器函数
{
	uint32_t i=10000;//防止在标志位检测函数卡死
	
    I2C_GenerateSTART(I2C2,ENABLE);//发送开始位
    while( I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS && (i--)>0 )//检测标志位
		     ;
    reset_count();//重置计数器i	
	
	I2C_SendData(I2C2,MPU6050_ADD);//发送从机地址
	while( I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)!=SUCCESS && (i--)>0 )//检测标志位
		     ;
	reset_count();//重置计数器i	
	
	I2C_SendData(I2C2,add);//发送从机寄存器地址（本质上是发一个字节的数据，mpu6050将其解读成从机寄存器地址）
	while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING)!=SUCCESS && (i--)>0 )//检测标志位
		     ;
	reset_count();//重置计数器i	
	
	I2C_SendData(I2C2,data);//发送数据
	while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)!=SUCCESS && (i--)>0 )//检测标志位
		     ;
                                                                                                   
	I2C_GenerateSTOP(I2C2,ENABLE);//发送停止位
}
 
uint8_t Mpu6050ReadReg(uint8_t add)//读寄存器函数
{
    uint8_t data;
	
	uint32_t i=10000;//防止在标志位检测函数卡死
	
    I2C_GenerateSTART(I2C2,ENABLE);//发送开始位
    while( I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS && (i--)>0 )//检测标志位
		     ;
    reset_count();//重置计数器i	
	
	I2C_SendData(I2C2,MPU6050_ADD);//发送从机地址
	while( I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)!=SUCCESS && (i--)>0 )//检测标志位
		     ;
	reset_count();//重置计数器i	
	
	I2C_SendData(I2C2,add);//发送从机寄存器地址（本质上是发一个字节的数据，mpu6050将其解读成从机寄存器地址）
	while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING)!=SUCCESS && (i--)>0 )//检测标志位
		     ;
	reset_count();//重置计数器i	
	
	I2C_GenerateSTART(I2C2,ENABLE);//发送开始位
    while( I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS && (i--)>0 )//检测标志位
		     ;
    reset_count();//重置计数器i
	
    I2C_SendData(I2C2,MPU6050_ADD|0x01);//发送从机寄存器地址（本质上是发一个字节的数据，mpu6050将其解读成从机寄存器地址）
	while( I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)!=SUCCESS && (i--)>0 )//检测标志位
		     ;
	reset_count();//重置计数器i
	
	I2C_AcknowledgeConfig(I2C2,DISABLE);//读最后一个数据之前关闭ACK
//    I2C_GenerateSTOP(I2C2,ENABLE);//发送停止位
	

	while( I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED)!=SUCCESS && (i--)>0 )//检测标志位
		    ;
	data=I2C_ReceiveData(I2C2);//读取数据，由于ack被关闭，主机读取完数据后不会再发送ack
	
    I2C_GenerateSTOP(I2C2,ENABLE);//发送停止位
	
    I2C_AcknowledgeConfig(I2C2,ENABLE);//重新打开ACK
	
    return data;	
}

void Mpu6050_Init()
{
	//初始化硬件I2C
	//初始化外设时钟//
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	//初始化IO口
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD;//复用开漏输出
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//初始化I2C
	I2C_InitTypeDef I2C_InitStructure;
	I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;//开启应答位
	I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;//7位地址
	I2C_InitStructure.I2C_ClockSpeed=50000;//时钟速率为50mhz
	I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;//时钟速率小于100mhz时这项不起作用
	I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;//I2C模式
	I2C_InitStructure.I2C_OwnAddress1=0x00;//主机地址为0x00
	I2C_Init(I2C2,&I2C_InitStructure);
	//IIC上电启动
	I2C_Cmd(I2C2,ENABLE);
	//硬件IIC初始化完成
	
	Mpu6050WriteReg(MPU6050_PWR_MGMT_1, 0x01);
	Mpu6050WriteReg(MPU6050_PWR_MGMT_2, 0x00);
	Mpu6050WriteReg(MPU6050_SMPLRT_DIV, 0x09);
	Mpu6050WriteReg(MPU6050_CONFIG, 0x06);
	Mpu6050WriteReg(MPU6050_GYRO_CONFIG, 0x18);
	Mpu6050WriteReg(MPU6050_ACCEL_CONFIG, 0x18);
}

void Mpu6050Getdata(AxisDataTypeDef * AxisDataPt)
{
   uint8_t DataH,DataL;
	
   DataH=Mpu6050ReadReg(MPU6050_ACCEL_XOUT_H);
   DataL=Mpu6050ReadReg(MPU6050_ACCEL_XOUT_L);
   (AxisDataPt->accx)=(DataH<<8)|DataL;
	                                  
   DataH=Mpu6050ReadReg(MPU6050_ACCEL_YOUT_H);
   DataL=Mpu6050ReadReg(MPU6050_ACCEL_YOUT_L);
   (AxisDataPt->accy)=(DataH<<8)|DataL; 

   DataH=Mpu6050ReadReg(MPU6050_ACCEL_ZOUT_H);
   DataL=Mpu6050ReadReg(MPU6050_ACCEL_ZOUT_L);
   (AxisDataPt->accz)=(DataH<<8)|DataL;

   DataH=Mpu6050ReadReg(MPU6050_GYRO_XOUT_H);
   DataL=Mpu6050ReadReg(MPU6050_GYRO_XOUT_L);
   (AxisDataPt->angaccx)=(DataH<<8)|DataL;

   DataH=Mpu6050ReadReg(MPU6050_GYRO_YOUT_H);
   DataL=Mpu6050ReadReg(MPU6050_GYRO_YOUT_L);
   (AxisDataPt->angaccy)=(DataH<<8)|DataL;

   DataH=Mpu6050ReadReg(MPU6050_GYRO_ZOUT_H);
   DataL=Mpu6050ReadReg(MPU6050_GYRO_ZOUT_L);
   (AxisDataPt->angaccz)=(DataH<<8)|DataL;
}






